import winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';
import path from 'path';
import fs from 'fs';
import config from '@config/index';

// 确保日志目录存在
const logDir = config.env.LOG_DIR;
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true });
}

// 自定义日志格式
const logFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss.SSS',
  }),
  winston.format.errors({ stack: true }),
  winston.format.json(),
  winston.format.printf((info) => {
    const { timestamp, level, message, stack, userId, action, resource, ...meta } = info;
    
    let logObject: any = {
      timestamp,
      level,
      message,
    };

    // 添加用户信息
    if (userId) {
      logObject.userId = userId;
    }

    // 添加操作信息
    if (action) {
      logObject.action = action;
    }

    // 添加资源信息
    if (resource) {
      logObject.resource = resource;
    }

    // 添加错误堆栈
    if (stack) {
      logObject.stack = stack;
    }

    // 添加其他元数据
    if (Object.keys(meta).length > 0) {
      logObject.meta = meta;
    }

    return JSON.stringify(logObject);
  })
);

// 开发环境控制台格式
const consoleFormat = winston.format.combine(
  winston.format.colorize(),
  winston.format.timestamp({
    format: 'HH:mm:ss',
  }),
  winston.format.printf((info) => {
    const { timestamp, level, message, userId, action } = info;
    let logMessage = `${timestamp} [${level}] ${message}`;
    
    if (userId) {
      logMessage += ` (User: ${userId})`;
    }
    
    if (action) {
      logMessage += ` (Action: ${action})`;
    }
    
    return logMessage;
  })
);

// 创建 Winston logger
const logger = winston.createLogger({
  level: config.env.LOG_LEVEL,
  format: logFormat,
  defaultMeta: {
    service: 'devops-smart-bot',
    version: process.env.npm_package_version || '1.0.0',
    environment: config.env.NODE_ENV,
  },
  transports: [
    // 错误日志文件
    new DailyRotateFile({
      filename: path.join(logDir, 'error-%DATE%.log'),
      datePattern: 'YYYY-MM-DD',
      level: 'error',
      maxSize: '20m',
      maxFiles: '14d',
      zippedArchive: true,
    }),

    // 组合日志文件
    new DailyRotateFile({
      filename: path.join(logDir, 'combined-%DATE%.log'),
      datePattern: 'YYYY-MM-DD',
      maxSize: '20m',
      maxFiles: '14d',
      zippedArchive: true,
    }),

    // 操作审计日志
    new DailyRotateFile({
      filename: path.join(logDir, 'audit-%DATE%.log'),
      datePattern: 'YYYY-MM-DD',
      level: 'info',
      maxSize: '20m',
      maxFiles: '30d',
      zippedArchive: true,
      format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json(),
        winston.format.printf((info) => {
          // 只记录包含 action 字段的日志到审计日志
          if (info.action) {
            return JSON.stringify(info);
          }
          return '';
        })
      ),
    }),
  ],
});

// 开发环境添加控制台输出
if (config.isDevelopment) {
  logger.add(
    new winston.transports.Console({
      format: consoleFormat,
    })
  );
}

// 生产环境错误处理
if (config.isProduction) {
  logger.exceptions.handle(
    new DailyRotateFile({
      filename: path.join(logDir, 'exceptions-%DATE%.log'),
      datePattern: 'YYYY-MM-DD',
      maxSize: '20m',
      maxFiles: '14d',
      zippedArchive: true,
    })
  );

  logger.rejections.handle(
    new DailyRotateFile({
      filename: path.join(logDir, 'rejections-%DATE%.log'),
      datePattern: 'YYYY-MM-DD',
      maxSize: '20m',
      maxFiles: '14d',
      zippedArchive: true,
    })
  );
}

// 扩展 logger 功能
class Logger {
  private winston: winston.Logger;

  constructor(winstonLogger: winston.Logger) {
    this.winston = winstonLogger;
  }

  // 基础日志方法
  error(message: string, error?: Error, meta?: object): void {
    this.winston.error(message, { stack: error?.stack, ...meta });
  }

  warn(message: string, meta?: object): void {
    this.winston.warn(message, meta);
  }

  info(message: string, meta?: object): void {
    this.winston.info(message, meta);
  }

  debug(message: string, meta?: object): void {
    this.winston.debug(message, meta);
  }

  // 审计日志方法
  audit(message: string, userId: string, action: string, resource?: string, meta?: object): void {
    this.winston.info(message, {
      userId,
      action,
      resource,
      ...meta,
    });
  }

  // HTTP 请求日志
  http(message: string, req: any, meta?: object): void {
    this.winston.info(message, {
      method: req.method,
      url: req.url,
      userAgent: req.get('User-Agent'),
      ip: req.ip,
      userId: req.user?.id,
      ...meta,
    });
  }

  // 性能日志
  performance(message: string, duration: number, meta?: object): void {
    this.winston.info(message, {
      duration,
      type: 'performance',
      ...meta,
    });
  }

  // 安全日志
  security(message: string, level: 'error' | 'warn' | 'info', meta?: object): void {
    this.winston[level](message, {
      type: 'security',
      ...meta,
    });
  }

  // 业务日志
  business(message: string, event: string, meta?: object): void {
    this.winston.info(message, {
      type: 'business',
      event,
      ...meta,
    });
  }

  // 创建子 logger（带有默认上下文）
  child(defaultMeta: object): Logger {
    const childLogger = this.winston.child(defaultMeta);
    return new Logger(childLogger);
  }

  // 获取 Winston logger 实例（用于特殊用途）
  getWinstonLogger(): winston.Logger {
    return this.winston;
  }
}

export default new Logger(logger);